#include <iostream>
#include <string>

#include <log4cxx/logger.h>
#include <log4cxx/xml/domconfigurator.h>

#include "MysqlConnPool.h"
#include "MysqlHelper.h"

#define THREAD_NUM 10
#define MYSQL_POOL_NUM 2 
#define LOG_CONF_FILE "./mysql_conn_pool_test_log.xml"
#define LOGGER_NAME "mysqlconnpooltest"

using std::cout;
using std::endl;
using std::string;

string g_mysqld_host;
string g_mysqld_port;
string g_mysqld_user;
string g_mysqld_passwd;
MysqlConnPool g_mysql_conn_pool;
log4cxx::LoggerPtr g_logger = log4cxx::Logger::getLogger(LOGGER_NAME);

void * thread_routine(void * arg) {
		string sql = "select Host, User, Password from user";
		while (true) {
				MYSQL_CONN * conn = g_mysql_conn_pool.acquire_conn();
				if (NULL == conn) { cout << "can not get conn from mysql conn pool" << endl; sleep(2); continue; }
				MysqlHelper mysql_helper;
				int res = mysql_helper.query(conn->mysql,  sql.c_str(), sql.size());
				if (res < 0) { cout << "mysql query error, sql:" << sql << ", res:" << res << endl; return NULL; }
				MYSQL_RES * mysql_res = mysql_store_result(conn->mysql);
				if (NULL == mysql_res) { cout << "mysql store result error, sql:" << sql << endl; return NULL; }
				MYSQL_ROW row;
				while ((row = mysql_fetch_row(mysql_res)) != NULL) {
						LOG4CXX_INFO(g_logger,  "Host:" << (row[0]?row[0]:"NULL") << ", User:" << (row[1]?row[1]:"NULL") \
										<< ", Password:" << (row[2]?row[2]:"NULL"));
										
				}
				mysql_free_result(mysql_res);
				g_mysql_conn_pool.release_conn(conn);
				sleep(1);
		}
		return NULL;
}

int show_usage(int argc, char * argv[]) {
		cout << "usage:" << argv[0] << " mysqld_host mysqld_port mysqld_user mysqld_passwd" << endl;
		return 1;
}

int test_mysql_pool(int argc, char * argv[]) {
		log4cxx::xml::DOMConfigurator::configure(LOG_CONF_FILE);
		if (argc != 5) {
				show_usage(argc, argv);
				return -1;
		}
		g_mysqld_host = argv[1];
		g_mysqld_port = argv[2];
		g_mysqld_user = argv[3];
		g_mysqld_passwd = argv[4];
		int res = mysql_library_init(-1, NULL, NULL);
		if (0 != res) { cout << "mysql library init fail, res:" << res << endl; return -1; }
		res = g_mysql_conn_pool.init(MYSQL_POOL_NUM, g_mysqld_host.c_str(), atoi(g_mysqld_port.c_str()), "mysql", \
										                                g_mysqld_user.c_str(), g_mysqld_passwd.c_str());
		if (res < 0) { cout << "mysql pool init error, res:" << res << endl; return -2; }
		pthread_t threads[THREAD_NUM];
		for(int i = 0; i < THREAD_NUM; i++) {
				pthread_create(&threads[i], NULL, thread_routine, NULL);
		}
		for(int i = 0; i < THREAD_NUM; i++) {
				pthread_join(threads[i], NULL);
		}
		cout << "oops...." << endl;
		return 1;
}


int main(int argc, char * argv[]) {
		test_mysql_pool(argc, argv);
		return 0;
}
		
